Skip to content

feat: home screen widgets for iOS and Android - #54

Open
neooriginal wants to merge 1 commit into
Termix-SSH:mainfrom
neooriginal:widgets
Open

feat: home screen widgets for iOS and Android#54
neooriginal wants to merge 1 commit into
Termix-SSH:mainfrom
neooriginal:widgets

Conversation

@neooriginal

@neooriginal neooriginal commented Aug 23, 2026

Copy link
Copy Markdown

Overview

Home screen widgets for iOS and Android, plus a Snippets shortcut in the Hosts header.

  • Added: Quick Connect, Server Status and Snippets widgets (WidgetKit + Android AppWidgets)
  • Added: Settings → Widgets display/privacy controls
  • Updated: Hosts header — Snippets shortcut; sort and filter moved beside the search field

Changes Made

Widgets never talk to the server. The app publishes a JSON snapshot into shared storage (App Group UserDefaults on iOS, SharedPreferences on Android) and the widget renders only that — no credentials leave the app, and a corrupt payload falls back to the signed-out card.

Widget Shows Tap
Quick Connect Hosts, status, load Opens a terminal session
Server Status CPU / memory per host Opens a terminal session
Snippets Your saved snippets Runs it on a host you pick

A snippet has no host of its own, so a tap opens Termix and asks where to run it, then executes it through the existing /snippets/execute endpoint. The last target is remembered and offered first, so the common case is two taps — which doubles as the confirmation a home-screen tap otherwise lacks. Only the snippet id travels in the deep link.

  • app/widgets/ — payload contract, snapshot builder, publisher, preferences, deep links, run sheet
  • modules/termix-widgets/ — native bridge, WidgetKit extension sources, Android providers and layouts
  • plugins/withTermixWidgets.js — creates the iOS extension target on prebuild (Android needs no plugin; the library manifest merges the receivers)
  • scripts/verify-widget-contract.cjs — fails when the TypeScript, Swift and Kotlin decoders drift apart

Signing out clears the snapshot, so host names can't linger on the home screen.

Checklist

  • Code follows project style guidelines
  • Supports mobile and desktop UI/app (if applicable)
  • Verified on a device build

Notes

iOS build requirements: the App Group group.<bundleId>.widgets must be enabled on both com.karmaa.termix and com.karmaa.termix.widgets, and the extension needs its own provisioning profile (run one interactive eas build first). The extension targets iOS 16 while the app stays at 15.1, because it uses WidgetKit layout APIs introduced there.

Verified: prebuild on both platforms, generated Xcode target structure, podspec, autolinking, decoder contract agreement, snapshot builder behaviour, deep-link parsing. Not verified: Swift/Kotlin compilation — needs a device build.

Pre-existing on main (not from this branch): format:check, tsc --noEmit and verify:android-network-security already fail.

🤖 AI assisted code using Claude Code

Adds Quick Connect, Server Status and Snippets widgets on both platforms,
plus a Snippets shortcut in the Hosts header.

Widgets never talk to the server: the app publishes a JSON snapshot into
shared storage (App Group UserDefaults on iOS, SharedPreferences on
Android) and the widget renders only that. No credentials leave the app,
and a corrupt or future-versioned payload falls back to the signed-out
card instead of breaking the launcher.

Tapping a host opens a terminal session on it. Tapping a snippet resolves
it in the app and asks which host to run it on, then executes it through
the existing /snippets/execute endpoint; the last target is remembered and
offered first. Only the snippet id travels in the deep link.

- app/widgets                 payload contract, snapshot builder,
                              publisher, preferences, deep links, run sheet
- modules/termix-widgets      native bridge, WidgetKit extension sources,
                              Android providers and layouts
- plugins/withTermixWidgets   creates the iOS extension target on prebuild
- scripts/verify-widget-contract.cjs
                              fails when the TypeScript, Swift and Kotlin
                              decoders drift apart

Settings gains a Widgets section (publish on/off, show addresses, include
offline, pinned only, snippets, command preview). Signing out clears the
snapshot. Sort and filter move beside the Hosts search field to make room
for the new shortcut.

The iOS extension targets iOS 16 and needs the group.<bundleId>.widgets
App Group enabled on both identifiers.
Copilot AI lite review requested due to automatic review settings August 23, 2026 22:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants